package org.skatiger.jrove.component.core;

import java.io.IOException;

import org.skatiger.jrove.ViewContext;
import org.skatiger.jrove.component.NamingContainer;
import org.skatiger.jrove.component.UIComponent;
import org.skatiger.jrove.component.UIComponentBase;
import org.skatiger.jrove.component.foreach.ForeachComponent;
import org.skatiger.jrove.component.foreach.ForeachStatus;
import org.skatiger.jrove.component.foreach.ForeachStatusIterator;
import org.skatiger.jrove.component.foreach.ForeachUtil;

public class ForEach extends UIComponentBase implements ForeachComponent,
        NamingContainer {
    private Object items;
    private String var;
    private String varStatus;
    private Integer begin;
    private Integer end;
    private Integer step;
    private ForeachStatusIterator _iterator;

    public void setBegin(Integer begin) {
        this.begin = begin;
    }

    public Integer getBegin() {
        return getPropertyValue("begin", begin);
    }

    public void setEnd(Integer end) {
        this.end = end;
    }

    public Integer getEnd() {
        return getPropertyValue("end", end);
    }

    public void setStep(Integer step) {
        this.step = step;
    }

    public Integer getStep() {
        return getPropertyValue("step", step);
    }

    public void setItems(Object items) {
        this.items = items;
    }

    public Object getItems() {
        return getPropertyValue("items", this.items);
    }

    public void setVar(String var) {
        this.var = var;
    }

    public String getVar() {
        return getPropertyValue("var", this.var);
    }

    public void setVarStatus(String varStatus) {
        this.varStatus = varStatus;
    }

    public String getVarStatus() {
        return getPropertyValue("varStatus", varStatus);
    }

    public ForeachStatusIterator getForeachStatusIterator() {
        if (this._iterator == null) {
            this._iterator = ForeachUtil.iterate(getItems(), getBegin(),
                    getEnd(), getStep());
        }
        return this._iterator;
    }

    @Override
    public boolean getRendersChildren() {
        return true;
    }

    @Override
    public void encodeChildren(ViewContext context) throws IOException {
        ForeachStatusIterator it = getForeachStatusIterator();
        Object previousVar = null;
        Object previousVarStatus = null;
        {//capture previous Object
            if (var != null) {
                previousVar = context.getAttribute(var);
            }
            if (varStatus != null) {
                previousVarStatus = context.getAttribute(varStatus);
            }
        }
        while (it.hasNext()) {
            Object _item = it.next();
            {//put table
                if (var != null && !var.trim().isEmpty()) {
                    context.setAttribute(var, _item);
                }
                if (varStatus != null && !varStatus.trim().isEmpty()) {
                    ForeachStatus _status = it.getStatus();
                    context.setAttribute(varStatus, _status);
                }
            }
            if (getChildCount() > 0) {
                for (UIComponent child : getChildren()) {
                    if (!child.isRendered()) {
                        continue;
                    }

                    child.encodeAll(context);
                }
            }
        }
        {//restore previous Object
            if (var != null) {
                if (previousVar != null) {
                    context.setAttribute(var, previousVar);
                } else {
                    context.removeAttribute(var);
                }
            }
            if (varStatus != null) {
                if (previousVarStatus != null) {
                    context.setAttribute(varStatus, previousVarStatus);
                } else {
                    context.removeAttribute(varStatus);
                }
            }
        }
    }

    @Override
    public String getClientId(ViewContext context) {
        String clientId = super.getClientId(context);
        int rowIndex = getForeachStatusIterator().getStatus().getIndex();
        if (rowIndex == -1) {
            return clientId;
        }
        StringBuilder bld = __getSharedStringBuilder();
        return bld.append(clientId).append(NamingContainer.SEPARATOR_CHAR)
                .append(rowIndex).toString();
    }

}
